/*
 * identity-pool.c
 *
 *  Created on: May 11, 2017
 *      Author: zhangzm
 */
#include <stdlib.h>
#include "log.h"
#include "identity-pool.h"

struct identity_pool
{
	Ctor ctor;
	Dtor dtor;
	int capacity, size;
	void* goods[0];
};

struct identity_pool* identity_pool_new(int capacity, Ctor ctor, Dtor dtor)
{
	struct identity_pool* pool = (struct identity_pool*)malloc( sizeof(*pool) + sizeof(pool->goods[0]) * capacity);
	pool->ctor = ctor;
	pool->dtor = dtor;
	pool->capacity = capacity;
	pool->size = 0;
	return pool;
}

void* identity_pool_get(struct identity_pool* pool)
{
	if (pool->size > 0)
	{
		pool->size--;
#ifdef DEBUG_WRITEx
		LOG_INFO("identity_pool_get %p", pool->goods[ pool->size ]);
#endif
		return pool->goods[ pool->size ];
	}
	else
	{
#ifdef DEBUG_WRITEx
		void* r = pool->ctor();
		LOG_INFO("identity_pool_get %p", r);
		return r;
#else
		return pool->ctor();
#endif
	}
}

int identity_pool_get_size(struct identity_pool* pool)
{
	return pool->size;
}

void identity_pool_put(struct identity_pool* pool, void* item)
{
#ifdef DEBUG_WRITEx
	LOG_INFO("identity_pool_put %p", item);
#endif
	if(!item){
		LOG_WARN("put a NULL, ignore");
		return;
	}
	if (pool->size < pool->capacity)
	{
		pool->goods[ pool->size ] = item;
		pool->size++;
	}
	else
	{
		pool->dtor(item);
	}
}

void identity_pool_delete(struct identity_pool* pool)
{
	for (int i=0; i<pool->size; ++i)
	{
#ifdef DEBUG_WRITEx
		LOG_INFO("identity_pool_delete %p", pool->goods[i]);
#endif
		pool->dtor(pool->goods[i]);
	}
	free(pool);
}
